package com.leenmvc.core.utils;

import com.leenmvc.core.utils.redis.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 
 *
 * @author Mark hongjl@gdruien.com
 * @since 1.0.0 2019-07-11
 */
@Component
public class SequenceUtil {

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 通过传入信息 获取序列号
     * @param moduleName 模块名称
     * @param dateFomat 时间格式
     * @param prefSeqNum 序列保存几位
     * @return 编码序列
     */
    public String getSeq(String moduleName,String dateFomat, Integer prefSeqNum) {
        String prefix = moduleName + GetYmd(dateFomat);
        String keyName = "sequence:"+prefix;
        String sequence = redisUtil.get(keyName);
        Long seqNum = null;
        if (sequence != null ) {
            seqNum = redisUtil.incr(keyName);
        } else if (sequence == null) {
            // 新增的统一为 1
            redisUtil.set(keyName,"1",3600*24);
            seqNum=1L;
        }
        return prefix + autoGenericCode(seqNum.toString(), prefSeqNum);
    }

//    public Integer getNextvalSeq(String prefix) {
//        Map<String, Object> params = new HashMap<>();
//        params.put("seqName", prefix);
//        // 租戶只能查詢租戶的数据，超级管理员可以查询所有的数据
//        DateFilterTenantId.setParamsByTenantId(params);
//        return  baseDao.getNextvalSeq(params);
//    }

//    public SequenceEntity getSequence(String name) {
//        Map<String, Object> params = new HashMap<>();
//        params.put("name", name);
//        // 租戶只能查詢租戶的数据，超级管理员可以查询所有的数据
//        DateFilterTenantId.setParamsByTenantId(params);
//        return baseDao.getSequence(params);
//    }

//    public QueryWrapper<SequenceEntity> getWrapper(Map<String, Object> params){
//        String name = (String) params.get("name");
//
//        QueryWrapper<SequenceEntity> wrapper = new QueryWrapper<>();
//        if(name!=null && !name.trim().equals("")) {
//            wrapper.eq(StringUtils.isNotBlank(name), "name", name);
//            wrapper.isNotNull(true,"name");
//        }
//        return wrapper;
//    }

    /**
     * 不够位数的在前面补0，保留num的长度位数字
     * @param code
     * @return
     */
    private String autoGenericCode(String code, int num) {
        String result = "";
        // 保留num的位数
        // 0 代表前面补充0
        // num 代表长度为4
        // d 代表参数为正数型
        result = String.format("%0" + num + "d", Integer.parseInt(code) + 1);

        return result;
    }

    /**
     * 获取时间
     * @param DataFormat :格式 YYYYMMDD,YYYYMM,YYMM,YYM,YYWW,YWW,YMM,YMD,YMDD
     * @return
     */
    public String GetYmd(String DataFormat){

        if (DataFormat.equals("YYYYMMDD")){
            SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");//设置日期格式
            return df.format(new Date());

        } else if (DataFormat.equals("YYYYMM")) {
            SimpleDateFormat df = new SimpleDateFormat("yyyyMM");//设置日期格式
            return df.format(new Date());

        } else if (DataFormat.equals("YYMM")) {
            SimpleDateFormat df = new SimpleDateFormat("yyMM");//设置日期格式
            return df.format(new Date());

        } else if (DataFormat.equals("YYM")) {
            SimpleDateFormat df = new SimpleDateFormat("yy");//设置日期格式
            String YY = df.format(new Date());

            df = new SimpleDateFormat("MM");//设置日期格式
            String MM =  df.format(new Date());

            return YY + MM;

        } else if (DataFormat.equals("YYWW")) {
            SimpleDateFormat df = new SimpleDateFormat("YY");//设置日期格式
            String YY = df.format(new Date());
            String WW = getSeqWeek();

            return YY + WW;
        } else if (DataFormat.equals("YWW")) {
            int Year = getNumberDate("YY");
            String YOne = GetYearOne(Year);
            String WW = getSeqWeek();

            return YOne + WW;
        } else if (DataFormat.equals("YMM")) {
            int Year = getNumberDate("YY");
            String YOne = GetYearOne(Year);

            SimpleDateFormat df = new SimpleDateFormat("MM");//设置日期格式
            String MM = df.format(new Date());

            return YOne + MM;
        } else if (DataFormat.equals("YMD")) {
            int Year = getNumberDate("YY");
            String YOne = GetYearOne(Year);

            int M = getNumberDate("MM");
            String MOne = GetOneMonth(M);

            int D = getNumberDate("dd");
            String DOne = GetOneDay(D);

            return YOne + MOne + DOne;
        } else if (DataFormat.equals("YMDD")) {
            int Year = getNumberDate("YY");
            String YOne = GetYearOne(Year);

            int M = getNumberDate("MM");
            String MOne = GetOneMonth(M);

            SimpleDateFormat df = new SimpleDateFormat("dd");//设置日期格式
            String DD = df.format(new Date());

            return YOne + MOne + DD;
        }
        return null;
    }

    /**
     * 获取一位的年月日
     * @param strDataForm
     * @return
     */
    public int getNumberDate(String strDataForm){
        SimpleDateFormat df = new SimpleDateFormat(strDataForm);//设置日期格式
        return Integer.parseInt(df.format(new Date()));
    }

    /**
     * 产生周序列,即得到当前时间所在的年度是第几周
     *
     * @return
     */
    public String getSeqWeek() {
        Calendar c = Calendar.getInstance(Locale.CHINA);
        String week = Integer.toString(c.get(Calendar.WEEK_OF_YEAR));
        if (week.length() == 1)
            week = "0" + week;
        return week;
    }

    /**
     * 获取一位年
     * @param Year
     * @return
     */
    public String GetYearOne(int Year) {
        String Y = null;
        switch (Year) {
            case 18:
                Y = "I";
                break;
            case 19:
                Y = "J";
                break;
            case 20:
                Y = "K";
                break;
            case 21:
                Y = "L";
                break;
            case 22:
                Y = "M";
                break;
            case 23:
                Y = "N";
                break;
            case 24:
                Y = "O";
                break;
            case 25:
                Y = "P";
                break;
            case 26:
                Y = "Q";
                break;
            case 27:
                Y = "R";
                break;
            case 28:
                Y = "S";
                break;
            case 29:
                Y = "T";
                break;
            case 30:
                Y = "U";
                break;
            case 31:
                Y = "V";
                break;
            case 32:
                Y = "W";
                break;
            case 33:
                Y = "X";
                break;
            case 34:
                Y = "Y";
                break;
            case 35:
                Y = "Z";
                break;
        }
        return Y;
    }

    /**
     * 获取一位的日期
     * @param day
     * @return
     */
    public String GetOneDay(int day){
        String OneDay = null;
        switch (day) {
            case 10:
                OneDay = "A";
                break;
            case 11:
                OneDay = "B";
                break;
            case 12:
                OneDay = "C";
                break;
            case 13:
                OneDay = "D";
                break;
            case 14:
                OneDay = "E";
                break;
            case 15:
                OneDay = "F";
                break;
            case 16:
                OneDay = "G";
                break;
            case 17:
                OneDay = "H";
                break;
            case 18:
                OneDay = "I";
                break;
            case 19:
                OneDay = "J";
                break;
            case 20:
                OneDay = "K";
                break;
            case 21:
                OneDay = "L";
                break;
            case 22:
                OneDay = "M";
                break;
            case 23:
                OneDay = "N";
                break;
            case 24:
                OneDay = "O";
                break;
            case 25:
                OneDay = "P";
                break;
            case 26:
                OneDay = "Q";
                break;
            case 27:
                OneDay = "R";
                break;
            case 28:
                OneDay = "S";
                break;
            case 29:
                OneDay = "T";
                break;
            case 30:
                OneDay = "U";
                break;
            case 31:
                OneDay = "V";
                break;
            default:
                OneDay = String.valueOf(day);
        }
        return OneDay;
    }

    /**
     * 获取一位的月份
     * @param M
     * @return
     */
    public String GetOneMonth(int M){
        String MM = null;
        switch (M) {
            case 10:
                MM = "A";
                break;
            case 11:
                MM = "B";
                break;
            case 12:
                MM = "C";
                break;
            default:
                MM = String.valueOf(M);
        }
        return MM;
    }

    /**
     * 计算2个日期之间相差的  以年、月、日为单位，各自计算结果是多少
     * 比如：2011-02-02 到  2017-03-02
     *                                以年为单位相差为：6年
     *                                以月为单位相差为：73个月
     *                                以日为单位相差为：2220天
     * @param fromDate
     * @param toDate
     * @return
     */
//    public static DayCompareEntity dayCompare(Date fromDate, Date toDate){
//        Calendar  from  =  Calendar.getInstance();
//        from.setTime(fromDate);
//        Calendar  to  =  Calendar.getInstance();
//        to.setTime(toDate);
//        //只要年月
//        int fromYear = from.get(Calendar.YEAR);
//        int fromMonth = from.get(Calendar.MONTH);
//        int toYear = to.get(Calendar.YEAR);
//        int toMonth = to.get(Calendar.MONTH);
//        int year = toYear  -  fromYear;
//        int month = toYear *  12  + toMonth  -  (fromYear  *  12  +  fromMonth);
//        int day = (int) ((to.getTimeInMillis()  -  from.getTimeInMillis())  /  (24  *  3600  *  1000));
//        return DayCompareEntity.builder().day(day).month(month).year(year).build();
//    }


    /**
     * 计算两个日期间相隔的周数
     *
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return
     */
    public static int computeWeek(Date startDate, Date endDate) {

        int weeks = 0;

        Calendar beginCalendar = Calendar.getInstance();
        beginCalendar.setTime(startDate);

        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(endDate);

        while (beginCalendar.before(endCalendar)) {

            // 如果开始日期和结束日期在同年、同月且当前月的同一周时结束循环
            if (beginCalendar.get(Calendar.YEAR) == endCalendar
                    .get(Calendar.YEAR)
                    && beginCalendar.get(Calendar.MONTH) == endCalendar
                    .get(Calendar.MONTH)
                    && beginCalendar.get(Calendar.DAY_OF_WEEK_IN_MONTH) == endCalendar
                    .get(Calendar.DAY_OF_WEEK_IN_MONTH)) {
                break;
            } else {
                beginCalendar.add(Calendar.DAY_OF_YEAR, 7);
                weeks += 1;
            }
        }
        return weeks;
    }

    /**
     * 获取今天
     * @return String
     * */
    public static String getToday(){
        return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
    }

    /**
     * 获取昨天
     * @return String
     * */
    public static String getYestoday(){
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.DATE,-1);
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time);
    }

    /**
     * 获取本月开始日期
     * @return String
     * **/
    public static String getMonthStart(){
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 00:00:00";
    }

    /**
     * 获取本月最后一天
     * @return String
     * **/
    public static String getMonthEnd(){
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 23:59:59";
    }

    /**
     * 获取本周的第一天
     * @return String
     * **/
    public static String getWeekStart(){
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.WEEK_OF_MONTH, 0);
        cal.set(Calendar.DAY_OF_WEEK, 2);
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 00:00:00";
    }

    /**
     * 获取本周的最后一天
     * @return String
     * **/
    public static String getWeekEnd(){
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
        cal.add(Calendar.DAY_OF_WEEK, 1);
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 23:59:59";
    }

    /**
     * 获取本年的第一天
     * @return String
     * **/
    public static String getYearStart(){
        return new SimpleDateFormat("yyyy").format(new Date())+"-01-01";
    }

    /**
     * 获取本年的最后一天
     * @return String
     * **/
    public static String getYearEnd(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH,calendar.getActualMaximum(Calendar.MONTH));
        calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date currYearLast = calendar.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(currYearLast)+" 23:59:59";
    }

    public static String[] getStartToEnd(String DateType) {
        String realStartDate = null;
        String realEndDate = null;

        if (DateType.equals("天")) {
            // 今天 00:00  到 明天
            realStartDate = DateUtils.format(new Date());
            realEndDate = DateUtils.format(DateUtils.addDateDays(new Date(), 1));
        } else if (DateType.equals("周")) {
            // 本周第一天到最后一天
            realStartDate = getWeekStart();
            realEndDate = getWeekEnd();
        } else if (DateType.equals("月")) {
            // 本月第一天到最后一天
            realStartDate = getMonthStart();
            realEndDate = getMonthEnd();
        } else if (DateType.equals("年")) {
            // 本年第一天到最后一天
            realStartDate = getYearStart();
            realEndDate = getYearEnd();
        }
        String [] arrDate = {realStartDate, realEndDate};
        return arrDate;
    }
}